<?
require_once(dirname(__FILE__) . '/../../classes/report_interface.inc.php');

abstract class LoggerModulePopularityReportBaseClass 
{
    protected $database;

    public function __construct(LoggerDatabase $database) 
    {
        $this->database = $database;
    }

    protected function GetDirsData($date1, $date2, $dirs, $start, $count)
    {
        $dirsSelect = array();
        $dirsJoin = '';
        $dirsWhere = '';
        $dirsGroup = '';
        for($i = 1; $i <= 2; $i++)
        {
            if (isset($dirs[$i-1]))
            {
                $dirsSelect[] = '`p`.`dir'.$i.'`, `s'.$i.'`.`string` AS `dir'.$i.'Name`';
                $dirsJoin .= 'LEFT JOIN `[PREF]module_popularity_strings` `s'.$i.'` ON `s'.$i.'`.`id`=`p`.`dir'.$i.'` ';
                $dirsWhere .= '`p`.`dir'.$i.'` = '.intval($dirs[$i-1]).' AND ';
            }
            else
            {
                break;
            }
        }
        $dirsSelect[] = '`p`.`dir'.$i.'`, `s'.$i.'`.`string` AS `dir'.$i.'Name`';
        $dirsJoin .= 'LEFT JOIN `[PREF]module_popularity_strings` `s'.$i.'` ON `s'.$i.'`.`id`=`p`.`dir'.$i.'` ';;
//        $dirsWhere .= '`p`.`dir'.$i.'` != 0 AND ';
        $dirsGroup .= '`p`.`dir'.$i.'`';

        $dirsSelect = implode(',', $dirsSelect);

        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';

        $SelectSQL = 'SELECT '.$dirsSelect.', SUM(`summ`) AS `summ` FROM (';
        $SelectSQL .= 'SELECT `dir1`,`dir2`,`dir3`, SUM(`p`.`count`) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity_archive` `p` ';
        $SelectSQL .= 'WHERE '.$dirsWhere.'`p`.`date`>='.$date1.' AND `p`.`date`<='.$date2.' ';
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';

        $SelectSQL .= 'UNION ALL ';

        $SelectSQL .= 'SELECT `dir1`,`dir2`,`dir3`, COUNT(*) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity` `p` ';
        $SelectSQL .= 'WHERE '.$dirsWhere.'`p`.`time`>='.$date1.' AND `p`.`time`<'.$date2.' + INTERVAL 1 DAY ';
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';

        $SelectSQL .= ') AS `p` ';
        $SelectSQL .= $dirsJoin;
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';
        $SelectSQL .= 'ORDER BY `summ` DESC ';
        $SelectSQL .= 'LIMIT '.$start.','.$count;

        $existsWhere = '';
        for($i = 1; $i <= 2; $i++)
        {
            if (isset($dirs[$i-1]) && $dirs[$i-1])
            {
                $existsWhere .= '`dir'.$i.'` = '.intval($dirs[$i-1]).' AND ';
            }
            else
            {
                break;
            }
        }
        $existsWhere .= '`dir'.($i+1).'` != 0 AND ';
        $lastDir = $i;

        $data = array();
        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);

        while ($row = $this->database->FetchAssoc($result))
        {
            $subDirs = 0;
            if ($lastDir <= 2)
            {
                    $SelectSQL = 'SELECT SUM(`summ`) AS `summ` FROM ( ';
                    $SelectSQL .= 'SELECT SUM(`count`) AS `summ` FROM `[PREF]module_popularity_archive` ';
                    $SelectSQL .= 'WHERE '.$existsWhere.'`dir'.$lastDir.'`='.intval($row['dir'.$lastDir]).' AND `date`>='.$date1.' AND `date`<='.$date2.' ';
                    $SelectSQL .= 'UNION ALL ';
                    $SelectSQL .= 'SELECT COUNT(*) AS `summ` FROM `[PREF]module_popularity` ';
                    $SelectSQL .= 'WHERE '.$existsWhere.'`dir'.$lastDir.'`='.intval($row['dir'.$lastDir]).' AND `time`>='.$date1.' AND `time`<'.$date2.' + INTERVAL 1 DAY ';
                    $SelectSQL .= ') AS `e`';

                    $resultExists = $this->database->Query($SelectSQL);
                    if (!$resultExists)
                         trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);
                    if ($rowExists = $this->database->FetchAssoc($resultExists))
                    {
                        if ($rowExists['summ'])
                            $subDirs = 1;
                    }
            }
            $row['subDirs'] = $subDirs;
            $data[] = $row;
        }
        $this->database->FreeResult($result);

        return $data;
    }
    

    protected function GetLinksData($date1, $date2, $dirs, $start, $count)
    {
        $dirsSelect = '';
        $dirsJoin = '';
        $dirsWhere = '';
        $dirsGroup = '';

        for ($i = 1; $i <= 3; $i++)
        {
            $dirsSelect .= '`d`.`dir'.$i.'`, `s'.$i.'`.`string` AS `dir'.$i.'Name`, ';
            $dirsJoin .= 'LEFT JOIN `[PREF]module_popularity_strings` `s'.$i.'` ON `s'.$i.'`.`id`=`d`.`dir'.$i.'` ';
            $dirsGroup .= '`d`.`dir'.$i.'`, ';
            if (isset($dirs[$i-1]))
            {
                $dirsWhere .= '`d`.`dir'.$i.'` = '.intval($dirs[$i-1]).' AND ';
            }
        }
        $dirsSelect .= '`d`.`file`, `f`.`string` AS `fileName`, ';
        $dirsSelect .= '`d`.`query`, `q`.`string` AS `queryName` ';
        $dirsJoin .= 'LEFT JOIN `[PREF]module_popularity_strings` `f` ON `f`.`id`=`d`.`file` ';
        $dirsJoin .= 'LEFT JOIN `[PREF]module_popularity_strings` `q` ON `q`.`id`=`d`.`query` ';
        $dirsGroup .= '`d`.`file`, ';
        $dirsGroup .= '`d`.`query` ';

        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';

        $SelectSQL = 'SELECT '.$dirsSelect.', SUM(`summ`) AS `summ`, \'archive\' AS `mode` FROM ( ';
        $SelectSQL .= 'SELECT '.$dirsGroup.', SUM(`d`.`count`) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity_archive` `d` ';
        $SelectSQL .= 'WHERE '.$dirsWhere.'`d`.`date`>='.$date1.' AND `d`.`date`<='.$date2.' ';
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';

        $SelectSQL .= 'UNION ALL ';

        $SelectSQL .= 'SELECT '.$dirsGroup.', COUNT(*) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity` `d` ';
        $SelectSQL .= 'WHERE '.$dirsWhere.'`d`.`time`>='.$date1.' AND `d`.`time`<'.$date2.' + INTERVAL 1 DAY ';
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';

        $SelectSQL .= ') AS `d` ';
        $SelectSQL .= $dirsJoin;
        $SelectSQL .= 'GROUP BY '.$dirsGroup.' ';
        $SelectSQL .= 'ORDER BY `summ` DESC, `dir1Name`, `dir2Name`, `dir3Name`, `fileName`, `queryName` ';
        $SelectSQL .= 'LIMIT '.$start.','.$count;

        $data = array();
        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);
        while ($row = $this->database->FetchAssoc($result))
        {
            $data[] = $row;
        }
        $this->database->FreeResult($result);
        return $data;
    }

    
    protected function GetTitlesData($date1, $date2, $start, $count)
    {
        $date1 = '\'' . mysql_escape_string($date1) . '\'';
        $date2 = '\'' . mysql_escape_string($date2) . '\'';

        $SelectSQL = 'SELECT `title`, `t`.`string` AS `titleStr`, SUM(`summ`) AS `summ`, \'archive\' AS `mode` FROM (';
        $SelectSQL .= 'SELECT `l`.`title`, SUM(`l`.`count`) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity_archive` `l` ';
        $SelectSQL .= 'WHERE `l`.`date`>='.$date1.' AND `l`.`date`<='.$date2.' ';
        $SelectSQL .= 'GROUP BY `l`.`title` ';

        $SelectSQL .= 'UNION ALL ';

        $SelectSQL .= 'SELECT `l`.`title`, COUNT(*) AS `summ` ';
        $SelectSQL .= 'FROM `[PREF]module_popularity` `l` ';
        $SelectSQL .= 'WHERE `l`.`time`>='.$date1.' AND `l`.`time`<'.$date2.' + INTERVAL 1 DAY ';
        $SelectSQL .= 'GROUP BY `l`.`title` ';

        $SelectSQL .= ') AS `__temp_query` ';
        $SelectSQL .= 'LEFT JOIN `[PREF]module_popularity_strings` `t` ON `t`.`id`=`__temp_query`.`title` ';
        $SelectSQL .= 'GROUP BY `__temp_query`.`title` ';
        $SelectSQL .= 'ORDER BY `summ` DESC, `titleStr` ';
        $SelectSQL .= 'LIMIT '.$start.','.$count;
            
        $data = array();
        $result = $this->database->Query($SelectSQL);
        if (!$result)
             trigger_error('Database Error: ' . $this->database->Error(), E_USER_ERROR);
        while ($row = $this->database->FetchAssoc($result))
        {
            $data[] = $row;
        }
        $this->database->FreeResult($result);
        return $data;
    }

    protected function FormatDirName($row)
    {
        $dirName = '';
        $arDirId = array();
        for ($i = 1; $i <= 3; $i++)
            if (isset($row['dir'.$i]))
            {
                $dirName .= '/' . $row['dir'.$i.'Name'];
                $arDirId[] = $row['dir'.$i];
            }
            else
                break;
        if (substr($dirName, -1) != '/')
            $dirName .= '/';

        return array(
            implode(',', $arDirId),
            $dirName
        );
    }

    protected function FormatUrlName($row)
    {
        
        $url = LoggerConfig::$myBaseUrl;
        $urlHuman = '';
        for ($i = 1; $i <= 3; $i++)
        {
            $url .= '/' . $row['dir'.$i.'Name'];        
            $urlHuman .= '/' . $row['dir'.$i.'Name'];

            if ($row['dir'.$i] == 0)
                break;
        }

        if (substr($url, -1) != '/')
        {
            $url .= '/';
            $urlHuman .= '/';
        }

        if (isset($row['fileName']) && $row['fileName'])
        {
            $url .= $row['fileName'];
            $urlHuman .= $row['fileName'];
        }
        if (isset($row['queryName']) && $row['queryName'])
        {
            $url .= '?' . $row['queryName'];
            $urlHuman .= '?' . $row['queryName'];
        }

        if (strlen($urlHuman) > 50)
            $urlHuman = substr($urlHuman, 0, 47) . '...';

        return array(
            $url,
            $urlHuman
        );
    }
}

class LoggerModulePopularityDirsReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;

        $xml = $root->ownerDocument;

        $name = $xml->createElement('report_name', 'Просмотры по путям');
        $root->appendChild($name);

        $data = $this->GetDirsData($date1, $date2, array(), $limit_start, $limit_count);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            list($dirId, $dirName) = $this->FormatDirName($row);
            $dataRow->setAttribute('dirName', $dirName);
            $dataRow->setAttribute('dirId', $dirId);
            $dataRow->setAttribute('subDirs', $row['subDirs']);
            $dataRow->setAttribute('summ', $row['summ']);
        }

        if (count($data) == $limit_count)
        {
            $dataMore = $xml->createElement('report_data_more');
            $dataMore->setAttribute('start', $limit_count);
            $dataMore->setAttribute('count', $limit_count);
            $root->appendChild($dataMore);
        }

        $xsl = dirname(__FILE__) . '/templates/dirs.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModulePopularityDirsExpandReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;
        
        $dirs = array();
        if (isset($params['dirs']) && $params['dirs'] != '')
        {
            $dirs = explode(',', $params['dirs']);
        }

        $xml = $root->ownerDocument;

        $data = $this->GetDirsData($date1, $date2, $dirs, $limit_start, $limit_count);

        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            list($dirId, $dirName) = $this->FormatDirName($row);
            $dataRow->setAttribute('dirName', $dirName);
            $dataRow->setAttribute('dirId', $dirId);
            $dataRow->setAttribute('subDirs', $row['subDirs']);
            $dataRow->setAttribute('depth', count($dirs));
            $dataRow->setAttribute('summ', $row['summ']);
        }

        $xsl = dirname(__FILE__) . '/templates/dirs_expand.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}

class LoggerModulePopularityLinksReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;
        
        $dirs = array();
        if (isset($params['dirs']) && $params['dirs'] != '')
        {
            $dirs = explode(',', $params['dirs']);
        }

        $xml = $root->ownerDocument;

        $name = $xml->createElement('report_name', 'Просмотры по ссылкам');
        $root->appendChild($name);

        $data = $this->GetLinksData($date1, $date2, $dirs, $limit_start, $limit_count);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            list($url, $urlHuman) = $this->FormatUrlName($row);
            list($dirId, $dirName) = $this->FormatDirName($row);
                
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('url', $url);
            $dataRow->setAttribute('urlHuman', $urlHuman);
            $dataRow->setAttribute('dirId', $dirId);
            $dataRow->setAttribute('fileId', $row['file']);
            $dataRow->setAttribute('queryId', $row['query']);
            $dataRow->setAttribute('summ', $row['summ']);
        }

        if (count($data) == $limit_count)
        {
            $dataMore = $xml->createElement('report_data_more');
            $dataMore->setAttribute('start', $limit_count);
            $dataMore->setAttribute('count', $limit_count);
            if (count($dirs) > 0)
                $dataMore->setAttribute('dirs', implode(',', $dirs));
            $root->appendChild($dataMore);
        }

        $xsl = dirname(__FILE__) . '/templates/links.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModulePopularityLinksMoreReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        if (!is_array($params) || !isset($params['start']))
            return false;

        $limit_start = intval($params['start']);
        $limit_count = 100;

        if (isset($params['count']))
            $limit_count = intval($params['count']);

        $dirs = array();
        if (isset($params['dirs']) && $params['dirs'] != '')
        {
            $dirs = explode(',', $params['dirs']);
        }

        $xml = $root->ownerDocument;

        $data = $this->GetLinksData($date1, $date2, $dirs, $limit_start, $limit_count);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            list($url, $urlHuman) = $this->FormatUrlName($row);
            list($dirId, $dirName) = $this->FormatDirName($row);

            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('url', $url);
            $dataRow->setAttribute('urlHuman', $urlHuman);
            $dataRow->setAttribute('dirId', $dirId);
            $dataRow->setAttribute('fileId', $row['file']);
            $dataRow->setAttribute('queryId', $row['query']);
            $dataRow->setAttribute('summ', $row['summ']);
        }
        $xsl = dirname(__FILE__) . '/templates/links_more.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModulePopularityTitlesReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        $limit_start = 0;
        $limit_count = 100;

        $xml = $root->ownerDocument;

        $name = $xml->createElement('report_name', 'Просмотры по заголовкам');
        $root->appendChild($name);

        $data = $this->GetTitlesData($date1, $date2, $limit_start, $limit_count);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $title = $row['titleStr'];
            $titleHuman = $title;
            if (function_exists('mb_strlen') && mb_strlen($titleHuman, 'UTF-8') > 100)
                $titleHuman = mb_substr($titleHuman, 0, 97, 'UTF-8') . '...';
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('title', $title);
            $dataRow->setAttribute('titleHuman', $titleHuman);
            $dataRow->setAttribute('titleId', $row['title']);
            $dataRow->setAttribute('summ', $row['summ']);
        }

        if (count($data) == $limit_count)
        {
            $dataMore = $xml->createElement('report_data_more');
            $dataMore->setAttribute('start', $limit_count);
            $dataMore->setAttribute('count', $limit_count);
            $root->appendChild($dataMore);
        }

        $xsl = dirname(__FILE__) . '/templates/titles.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}


class LoggerModulePopularityTitlesMoreReport extends LoggerModulePopularityReportBaseClass implements LoggerReportInterface
{
    public function __construct(LoggerDatabase $database) 
    {
        parent::__construct($database);
    }

    public function GetReport($root, $date1, $date2, $params = false)
    {
        if (!is_array($params) || !isset($params['start']))
            return false;

        $limit_start = intval($params['start']);
        $limit_count = 100;

        if (isset($params['count']))
            $limit_count = intval($params['count']);

        $xml = $root->ownerDocument;

        $data = $this->GetTitlesData($date1, $date2, $limit_start, $limit_count);
        $reportData = $xml->createElement('report_data');
        $root->appendChild($reportData);

        foreach($data as $row)
        {
            $title = $row['titleStr'];
            $titleHuman = $title;
            if (function_exists('mb_strlen') && mb_strlen($titleHuman, 'UTF-8') > 100)
                $titleHuman = mb_substr($titleHuman, 0, 97, 'UTF-8') . '...';
            $dataRow = $xml->createElement('row');
            $reportData->appendChild($dataRow);
            $dataRow->setAttribute('title', $title);
            $dataRow->setAttribute('titleHuman', $titleHuman);
            $dataRow->setAttribute('titleId', $row['title']);
            $dataRow->setAttribute('summ', $row['summ']);
        }

        $xsl = dirname(__FILE__) . '/templates/titles_more.xsl';
        $pi = $xml->createProcessingInstruction('xml-stylesheet', 'type="text/xsl" href="'.$xsl.'"');
        $xml->insertBefore($pi, $root);
        return true;
    }
}